#!/usr/bin/python3
# ******************************************************************************
# Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved.
# licensed under the Mulan PSL v2.
# You can use this software according to the terms and conditions of the Mulan PSL v2.
# You may obtain a copy of Mulan PSL v2 at:
#     http://license.coscl.org.cn/MulanPSL2
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
# PURPOSE.
# See the Mulan PSL v2 for more details.
# ******************************************************************************/
import argparse
import json
import subprocess

import requests

BASE_URL = "http://127.0.0.1:8090/"
method_dict = {
    "get": requests.get,
    "post": requests.post,
    "put": requests.put,
    "delete": requests.delete
}
HEARD = "Content-Type:application/json"


def parse_arg(parse: argparse.ArgumentParser):
    parse.add_argument('--repo', default='oe21.03', type=str, action='store', nargs='?', help="repo name")
    return parse


def _run_cli(cli):
    try:
        result = subprocess.run([cli], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
        return result.stdout.decode('utf-8')
    except subprocess.CalledProcessError:
        print(f"[ERROR] excute {cli} failed")
        return


def check_repo(repo):
    query_dbs_cli = "pkgship dbs"
    result = _run_cli(query_dbs_cli)
    if not result or repo not in result:
        print(f"[ERROR] {repo} not provided")
        return False
    return True


def _request(url, method, **kwargs):
    try:
        if method not in method_dict:
            raise requests.HTTPError(f"no this method {method}")
        call_url = method_dict.get(method)
        response = call_url(url=url, **kwargs)
        return response.text
    except requests.HTTPError as e:
        print(f'[ERROR] call {url} failed: {str(e)}')
        return


def get_all_bin_rpm(repo):
    query_url = "packages/bin"
    return _get_all_rpm(repo, query_url)


def get_all_src_rpm(repo):
    query_url = "packages/src"
    return _get_all_rpm(repo, query_url)


def _get_all_rpm(repo, query_url):
    rpm_name_list = list()
    query_body = {
        "database_name": repo,
        "page_num": 1,
        "page_size": 200,
        "query_pkg_name": None
    }
    result = _request(BASE_URL + query_url, method="get", params=query_body)
    try:
        if result:
            result_content = json.loads(result)
            total_page = result_content.get('total_page')
            _parse_content(rpm_name_list, result_content)
            for page_index in range(2, total_page + 1):
                query_body['page_num'] = page_index
                result = _request(BASE_URL + query_url, method="get", params=query_body)
                result_content = json.loads(result)
                _parse_content(rpm_name_list, result_content)
    except TypeError:
        print(f'[ERROR] get all rpm failed, url is {BASE_URL + query_url} param is {query_body}')
        return []
    return rpm_name_list


def _parse_content(rpm_name_list, result_content):
    if result_content.get('resp'):
        for rpm_info in result_content.get('resp'):
            rpm_name_list.append(rpm_info.get('pkg_name'))


def _get_depend_info(rpm_name, repo, query_url, depend_type, depend_info_dict):
    query_body = {
        "packagename": [
            rpm_name
        ],
        "depend_type": depend_type,
        "parameter": {
            "db_priority": [
                repo
            ],
            "level": 1
        }
    }
    result = _request(BASE_URL + query_url, method='post', json=query_body)
    try:
        if result:
            print(f"result is {result}")
            result_content = json.loads(result)
            binary_list = result_content.get('resp')['binary_list']
            depend_info_dict[rpm_name] = binary_list
    except TypeError:
        print(f'[ERROR] get {rpm_name} depend info failed, url is {BASE_URL + query_url} param is {query_body}')

    return depend_info_dict


def get_install_depend(rpm_list, repo):
    depend_info_dict = dict
    query_url = "dependinfo/dependlist"
    depend_type = "installdep"
    for rpm_name in rpm_list:
        _get_depend_info(rpm_name=rpm_name, repo=repo, query_url=query_url, depend_type=depend_type,
                         depend_info_dict=depend_info_dict)

    print(len(depend_info_dict))
    print(depend_info_dict["Judy"])


if __name__ == '__main__':
    # parser = argparse.ArgumentParser()
    # parser = parse_arg(parser)
    # args = parser.parse_args()
    # repo = args.repo
    # if check_repo(repo):
    #     rpm_name_list = get_all_bin_rpm(repo=repo)
    #     get_install_depend(rpm_name_list[0:5], repo)
    # query_body = {"packagename": ["Judy"],
    #               "depend_type": "bedep",
    #               "parameter": {"db_priority": ["openeuler21.03"],
    #                             "search_type": "build",
    #                             "with_subpack": True,
    #                             "packtype": "binary"},
    #               "node_name": "Judy",
    #               "node_type": "binary"
    #               }
    #
    # result = _request(BASE_URL + "dependinfo/dependgraph", method='post', json=query_body)
    # print(result)
    query_body = {
        "database_name": "fedora32",
        "page_num": 5,
        "page_size": 200,
        "query_pkg_name": None
    }
    result = _request(BASE_URL + "packages/bin", method="get", params=query_body)
    result_content = json.loads(result)
    total_page = result_content.get('total_count')
    print(total_page)
